package com.chenfan.magic.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

/**
 * AES对称加密/解密工具类
 *
 * @author troy
 * @email 1747128171@qq.com
 * @date 19:20 2019/12/1 0001
 */
@Slf4j
public class AES {

    /**
     * 使用AES-128-CBC加密模式，key需要为16位,key和iv可以相同！
     */
    public static String KEY = "abcdefgabcdefg-zhouxinimei.-3620";

    public static String IV = "1234567890123456";

    /**
     * "算法/模式/补码方式"
     */
    private static final String ALGORITHM = "AES/ECB/PKCS5Padding";

    /*****************************************************
     * AES加密
     * @param content 加密内容
     * @param key 加密密码，由字母或数字组成
     * 此方法使用AES-128-ECB加密模式，key需要为16位
     * 加密解密key必须相同，如：abcd1234abcd1234
     * @return 加密密文
     ****************************************************/

    public static String encrypt(String content, String key) {
        if (StringKit.isBlank(key)) {
            key = KEY;
        }
        try {
            //获得密码的字节数组
            byte[] raw = key.getBytes();
            //根据密码生成AES密钥
            SecretKeySpec skey = new SecretKeySpec(raw, "AES");
            //根据指定算法ALGORITHM自成密码器
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            //初始化密码器，第一个参数为加密(ENCRYPT_MODE)或者解密(DECRYPT_MODE)操作，第二个参数为生成的AES密钥
            cipher.init(Cipher.ENCRYPT_MODE, skey);
            //获取加密内容的字节数组(设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
            byte[] byte_content = content.getBytes("utf-8");
            //密码器加密数据
            byte[] encode_content = cipher.doFinal(byte_content);
            //将加密后的数据转换为字符串返回
            return Base64.encodeBase64String(encode_content);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /*****************************************************
     * AES解密
     * @param content 加密密文
     * @param key 加密密码,由字母或数字组成
     * 此方法使用AES-128-ECB加密模式，key需要为16位
     * 加密解密key必须相同
     * @return 解密明文
     ****************************************************/

    public static String decrypt(String content, String key) {
        if (StringKit.isBlank(key)) {
            key = KEY;
        }
        try {
            //获得密码的字节数组
            byte[] raw = key.getBytes();
            //根据密码生成AES密钥
            SecretKeySpec skey = new SecretKeySpec(raw, "AES");
            //根据指定算法ALGORITHM自成密码器
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            //初始化密码器，第一个参数为加密(ENCRYPT_MODE)或者解密(DECRYPT_MODE)操作，第二个参数为生成的AES密钥
            cipher.init(Cipher.DECRYPT_MODE, skey);
            //把密文字符串转回密文字节数组
            byte[] encode_content = Base64.decodeBase64(content);
            //密码器解密数据
            byte[] byte_content = cipher.doFinal(encode_content);
            //将解密后的数据转换为字符串返回
            return new String(byte_content, "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String encrypt(String content) {
        return encrypt(content, null);
    }

    public static String decrypt(String content) {
        return decrypt(content, null);
    }

    /*****************************************************
     * AES加密解密测试
     * @param args
     * @return
     ****************************************************/

    public static void main(String[] args) {
        String content = "加密解密测试";
        log.info("加密content：" + content);
        String key = "abcd1234abcd1234";
        log.info("加密key：" + key);
        String enResult = encrypt(content);
        log.info("加密result：" + enResult);
        String deResult = decrypt(enResult);
        log.info("解密result：" + deResult);
    }
}
